/*
 * @Author: your name
 * @Date: 2021-03-30 11:55:42
 * @LastEditTime: 2021-09-27 16:39:07
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /egg-ts/app/middleware/jwt.ts
 */

const isCheckeUrl = (url: string, arrAuth: []) => {
  const tempUrl = url.split('/api/v1/')[1].replace(/\//g, '_');
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  return arrAuth.includes(tempUrl);
};

export default function(_options, app) {
  return async function userInterceptor(ctx, next) {
    try {
      const url = ctx.request.url.split('?')[0];
      let authToken = ctx.header.authorization; // 获取header里的authorization
      // 本地测试跳过验证 或者 skipPath中 indexof到ur
      if (ctx.app.config.jwt.skipValidation || ctx.app.config.jwt.skipPath.some(el => url.indexOf(el) !== -1) ) {
        await next();
      } else if (authToken) {
        authToken = authToken.substring(7);
        const res: any = ctx.helper.verifyToken(authToken); // 解密获取的Token
        if (res && res.userid) {
          // 如果需要限制单端登陆或者使用过程中废止某个token，或者更改token的权限。也就是说，一旦 JWT 签发了，在到期之前就会始终有效
          // 此处使用redis进行保存
          const redis_token = await app.redis.get(res.userid); // 获取保存的token
          if (redis_token && authToken !== JSON.parse(redis_token).token && app.config.isLoginOffline) {
            ctx.body = { code: 1006, msg: '您的账号已在其他地方登录或已退出登录', success: false };
          } else {
            // 判断当前url是否有权限
            if (ctx.app.config.jwt.ignore.includes(url) || isCheckeUrl(url, JSON.parse(redis_token).auth)) {
              ctx.locals.userid = res.userid;
              await ctx.app.redis.set(JSON.parse(redis_token).id, redis_token, 'ex', 60 * 60 * 24 * 7); // 每次访问更新redis
              await next();
            } else {
              ctx.body = { code: 1010, msg: '无权限', success: false };
            }
          }
        } else {
          ctx.body = { code: 1007, msg: '登录状态已过期', success: false };
        }
      } else {
        ctx.body = { code: 1008, msg: '请登陆后再进行操作', success: false };
      }
    } catch (err) {
      console.log(err);
      ctx.body = { code: 1009, msg: '服务器开小差了，请稍后再试', success: false };
    }
  };
}
